package com.yuyou.fn.wage.service.impl;

import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.toolkit.IdWorker;
import com.yuyou.fn.common.constant.JobNatureEnum;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.*;
import com.yuyou.fn.educational.entity.CourseClass;
import com.yuyou.fn.educational.entity.Teacher;
import com.yuyou.fn.educational.service.ICourseClassService;
import com.yuyou.fn.educational.service.ITeacherService;
import com.yuyou.fn.platform.permission.DataPermission;
import com.yuyou.fn.platform.service.ISysUserRoleService;
import com.yuyou.fn.report.service.IClassLectureDetailService;
import com.yuyou.fn.report.vo.ClassLectureDayDetailVo;
import com.yuyou.fn.report.vo.ClassLectureDetailQueryVo;
import com.yuyou.fn.wage.entity.WageCoefficientPerformance;
import com.yuyou.fn.wage.entity.WageTeacherDollars;
import com.yuyou.fn.wage.mapper.WageTeacherDollarsMapper;
import com.yuyou.fn.wage.service.IWageCoefficientPerformanceService;
import com.yuyou.fn.wage.service.IWageTeacherDollarsService;
import com.yuyou.fn.wage.vo.TeacherDollarsDetailVo;
import com.yuyou.fn.wage.vo.TeacherDollarsUpdateVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 *
 * WageTeacherDollars 表数据服务层接口实现类
 *
 */
@Service
public class WageTeacherDollarsServiceImpl extends SuperServiceImpl<WageTeacherDollarsMapper, WageTeacherDollars,Long> implements IWageTeacherDollarsService {
    @Resource
    private IClassLectureDetailService classLectureDetailService;

    @Resource
    private IWageCoefficientPerformanceService wageCoefficientPerformanceService;

    @Resource
    private ITeacherService teacherService;

    @Resource
    private ICourseClassService courseClassService;

    @Resource
    private ISysUserRoleService sysUserRoleService;

    @Override
    public List<WageTeacherDollars> findWageTeacherDollars(List<Long> teacherIds, String startDate, String endDate) {
        if (teacherIds==null || teacherIds.size()==0){
            return Collections.EMPTY_LIST;
        }
        Example<WageTeacherDollars> example=WageTeacherDollars.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andIn("teacherId",teacherIds);
        criteria.andGreaterThanOrEqualTo("classDate",startDate);
        criteria.andLessThanOrEqualTo("classDate",endDate);
        return this.findListByExample(example);
    }

    @Override
    @Transactional
    public List<TeacherDollarsDetailVo> findTeacherDollarsDetailListByPermission(String payMonth,DataPermission dataPermission,ClassLectureDetailQueryVo classLectureDetailQueryVo, Integer confirmStatus) {

        if (dataPermission.getBusTeamIds()==null || dataPermission.getBusTeamIds().size()<=0){
            return Collections.EMPTY_LIST;
        }

        return this.findTeacherDollarsDeatilList(payMonth,dataPermission.getBusTeamIds(),classLectureDetailQueryVo,confirmStatus);
    }

    @Override
    @Transactional
    public List<TeacherDollarsDetailVo> findAllTeacherDollarsDetailList(String payMonth, ClassLectureDetailQueryVo classLectureDetailQueryVo, Integer confirmStatus) {
        return this.findTeacherDollarsDeatilList(payMonth,null,classLectureDetailQueryVo,confirmStatus);
    }

    private List<TeacherDollarsDetailVo> findTeacherDollarsDeatilList(String payMonth, List<Long> busTeamIds, ClassLectureDetailQueryVo classLectureDetailQueryVo, Integer confirmStatus){
        List<ClassLectureDayDetailVo> classLectureDayDetailVoList=classLectureDetailService.findDayLectureDetail(classLectureDetailQueryVo,busTeamIds);
        if (classLectureDayDetailVoList==null || classLectureDayDetailVoList.size()==0){
            return Collections.EMPTY_LIST;
        }
        List<Long> teacherIds= BeanUtils.toList(classLectureDayDetailVoList,"teacherId");
        teacherIds= Utils.removeDuplicate(teacherIds);

        List<Long> classIds=BeanUtils.toList(classLectureDayDetailVoList,"classId");
        List<CourseClass> courseClassList=courseClassService.findByIds(classIds,"classId","className","segmentNo","lectureAmount","classNo");
        Map<Long,CourseClass> courseClassMap=BeanUtils.toMap(courseClassList,"classId");

        List<WageTeacherDollars> wageTeacherDollarsList=this.findWageTeacherDollars(teacherIds,Utils.formatDate(classLectureDetailQueryVo.getStartClassDate(),"yyyy-MM-dd"),Utils.formatDate(classLectureDetailQueryVo.getEndClassDate(),"yyyy-MM-dd"));
        Map<String,WageTeacherDollars> dollarsMap=new HashMap<>();
        List<WageCoefficientPerformance> wageCoefficientPerformanceList=wageCoefficientPerformanceService.findCoefficientPerformanceByEmployeeIds(teacherIds);
        Map<Long,WageCoefficientPerformance> coefficientPerformanceMap=BeanUtils.toMap(wageCoefficientPerformanceList,"employeeId");
        List<Teacher> teacherList=teacherService.findByIds(teacherIds);
        Map<Long,Teacher> teacherMap=BeanUtils.toMap(teacherList,"teacherId");
        if (wageTeacherDollarsList!=null){
            for (WageTeacherDollars wageTeacherDollars:wageTeacherDollarsList){
                String key=wageTeacherDollars.getTeacherId()+"_"+wageTeacherDollars.getClassId()+"_"+wageTeacherDollars.getClassDate();
                dollarsMap.put(key,wageTeacherDollars);
            }
        }
        List<TeacherDollarsDetailVo> teacherDollarsDetailVos=new ArrayList<>(classLectureDayDetailVoList.size());
        List<WageTeacherDollars> saveList=new ArrayList<>();
        for (ClassLectureDayDetailVo classLectureDayDetailVo:classLectureDayDetailVoList){
            Long teacherId=classLectureDayDetailVo.getTeacherId();
            String key=classLectureDayDetailVo.getTeacherId()+"_"+classLectureDayDetailVo.getClassId()+"_"+classLectureDayDetailVo.getClassDate();
            TeacherDollarsDetailVo teacherDollarsDetailVo=new TeacherDollarsDetailVo();
            teacherDollarsDetailVo.setPayMonth(payMonth!=null?Utils.parseDate(payMonth,"yyyy-MM"):null);
            BeanUtils.copyProperties(teacherDollarsDetailVo,classLectureDayDetailVo);
            Teacher teacher=teacherMap.get(teacherId);
            if (teacher!=null){
                teacherDollarsDetailVo.setIdNo(teacher.getIdNo());
                teacherDollarsDetailVo.setJobNature(teacher.getJobNature().intValue());
                teacherDollarsDetailVo.setTeacherName(teacher.getTeacherName());
                teacherDollarsDetailVo.setPhoneNo(teacher.getPhoneNo());
            }
            CourseClass courseClass=courseClassMap.get(classLectureDayDetailVo.getClassId());
            if (courseClass!=null){
                teacherDollarsDetailVo.setSegmentNo(courseClass.getSegmentNo());
                teacherDollarsDetailVo.setLectureAmount(courseClass.getLectureAmount());
                teacherDollarsDetailVo.setClassNo(courseClass.getClassNo());
            }

            WageTeacherDollars wageTeacherDollars=dollarsMap.get(key);
            if (wageTeacherDollars!=null){
                BeanUtils.copyProperties(teacherDollarsDetailVo,wageTeacherDollars);
                if (wageTeacherDollars.getConfirmStatus()!=1){
                    WageCoefficientPerformance wageCoefficientPerformance=coefficientPerformanceMap.get(teacherId);
                    WageTeacherDollars update=null;
                    if (wageCoefficientPerformance!=null){
                        double coefficientPerformance=wageTeacherDollars.getCoefficientPerformance()==null?0d:wageTeacherDollars.getCoefficientPerformance().doubleValue();
                        double check=wageCoefficientPerformance.getCoefficientPerformance()==null?0d:wageCoefficientPerformance.getCoefficientPerformance().doubleValue();
                        if (coefficientPerformance!=check){
                            update=new WageTeacherDollars();
                            update.setTeacherDollarsId(wageTeacherDollars.getTeacherDollarsId());
                            update.setCoefficientPerformance(wageCoefficientPerformance.getCoefficientPerformance());
                        }
                        String salaryAccount=wageCoefficientPerformance.getSalaryAccount()==null?"":wageCoefficientPerformance.getSalaryAccount();
                        String checkAccount=wageTeacherDollars.getSalaryAccount()==null?"":wageTeacherDollars.getSalaryAccount();
                        if (!salaryAccount.equals(checkAccount)){
                            if (update==null){
                                update=new WageTeacherDollars();
                                update.setTeacherDollarsId(wageTeacherDollars.getTeacherDollarsId());
                            }
                            update.setSalaryAccount(wageCoefficientPerformance.getSalaryAccount());
                        }
                    }

                    if (update!=null){
                        this.updateSelectiveById(update);
                    }

                    teacherDollarsDetailVo.setCoefficientPerformance(wageCoefficientPerformance==null?0.0d:wageCoefficientPerformance.getCoefficientPerformance());

                }
            }else {
                WageCoefficientPerformance wageCoefficientPerformance=coefficientPerformanceMap.get(teacherId);
                WageTeacherDollars saveVo=new WageTeacherDollars();
                saveVo.setTeacherDollarsId(IdWorker.getId());
                saveVo.setClassDate(classLectureDayDetailVo.getClassDate());
                saveVo.setConfirmStatus(0);
                saveVo.setClassId(classLectureDayDetailVo.getClassId());
                saveVo.setBaseDollar(this.findGradeDefault(classLectureDayDetailVo.getGradeId()));
                saveVo.setCoefficientPerformance(wageCoefficientPerformance==null?0.0d:wageCoefficientPerformance.getCoefficientPerformance());
                saveVo.setSpecialDollar(BigDecimal.ZERO);
                saveVo.setTeacherId(classLectureDayDetailVo.getTeacherId());
                saveVo.setCreateTime(TimeUtils.now());
                saveVo.setUpdateTime(TimeUtils.now());
                BeanUtils.copyProperties(teacherDollarsDetailVo,saveVo);
                saveList.add(saveVo);
            }
            if (confirmStatus!=null && confirmStatus==teacherDollarsDetailVo.getConfirmStatus()){
                teacherDollarsDetailVos.add(teacherDollarsDetailVo);
            }else if (confirmStatus==null){
                teacherDollarsDetailVos.add(teacherDollarsDetailVo);
            }

        }
        if (saveList.size()>0){
            this.insertBatch(saveList);
        }
        return teacherDollarsDetailVos;
    }

    private BigDecimal findGradeDefault(Long gradeId){
        if (gradeId.equals(33L)){
            return new BigDecimal(470);
        }else {
            return new BigDecimal(370);
        }
    }

    @Override
    public void updateTeacherDollars(TeacherDollarsUpdateVo teacherDollarsUpdateVo) {
        if (teacherDollarsUpdateVo.getTeacherDollarsId()==null){
            throw new BusException("请传入id");
        }
        WageTeacherDollars check=this.findById(teacherDollarsUpdateVo.getTeacherDollarsId());
        if (check!=null && check.getConfirmStatus()==1){
            throw new BusException("确认的信息不可以更改");
        }
        WageTeacherDollars wageTeacherDollars=new WageTeacherDollars();
        BeanUtils.copyProperties(wageTeacherDollars,teacherDollarsUpdateVo);
        wageTeacherDollars.setUpdateTime(TimeUtils.now());
        this.updateSelectiveById(wageTeacherDollars);
    }

    @Override
    public void confirmTeacherDollars(List<Long> teacherDollarsIds) {
        if (teacherDollarsIds==null || teacherDollarsIds.size()<=0){
            throw new BusException("未传入要更改的信息");
        }
        List<WageTeacherDollars> wageTeacherDollarsList=this.findByIds(teacherDollarsIds);
        List<Long> teacherIds = BeanUtils.toList(wageTeacherDollarsList, "teacherId");


        List<Teacher> teacherList=teacherService.findByIds(teacherIds,"teacherId","teacherName");
        Map<Long, Teacher> teacherMap = BeanUtils.toMap(teacherList, "teacherId");

        for (WageTeacherDollars wageTeacherDollars:wageTeacherDollarsList){
            Long teacherId=wageTeacherDollars.getTeacherId();
            Teacher teacher=teacherMap.get(teacherId);
            if (StringUtils.isEmpty(wageTeacherDollars.getSalaryAccount())){
                throw new BusException(teacher.getTeacherName()+"老师尚未维护工资账号，请先在“绩效系数维护”报表进行录入后再查询确认");
            }
        }



        WageTeacherDollars wageTeacherDollars=new WageTeacherDollars();
        wageTeacherDollars.setConfirmStatus(1);
        wageTeacherDollars.setConfirmTime(TimeUtils.now());
        Principals.Principal principal= Principals.get();
        if (principal==null){
            throw new BusException("查不到登录人,请重新登录");
        }
        wageTeacherDollars.setOperatorId(principal.id);
        wageTeacherDollars.setOperatorName(principal.name);
        Example<WageTeacherDollars> example=WageTeacherDollars.createExample();
        example.createCriteria().andIn("teacherDollarsId",teacherDollarsIds);
        this.updateSelectiveByExample(wageTeacherDollars,example);
    }

    @Override
    public void cancelTeacherDollars(List<Long> teacherDollarsIds) {
        if (teacherDollarsIds==null || teacherDollarsIds.size()<=0){
            throw new BusException("未传入要更改的信息");
        }
        WageTeacherDollars wageTeacherDollars=new WageTeacherDollars();
        wageTeacherDollars.setConfirmStatus(0);
        wageTeacherDollars.setUpdateTime(TimeUtils.now());
        Principals.Principal principal= Principals.get();
        if (principal==null){
            throw new BusException("查不到登录人,请重新登录");
        }
        wageTeacherDollars.setOperatorId(principal.id);
        wageTeacherDollars.setOperatorName(principal.name);
        Example<WageTeacherDollars> example=WageTeacherDollars.createExample();
        example.createCriteria().andIn("teacherDollarsId",teacherDollarsIds);
        this.updateSelectiveByExample(wageTeacherDollars,example);
    }

    @Override
    public SXSSFWorkbook exportWageTeacherDollars(String payMonth, DataPermission dataPermission, ClassLectureDetailQueryVo classLectureDetailQueryVo, Integer status){
        List<TeacherDollarsDetailVo> teacherDollarsDetailList = this.findTeacherDollarsDetailListByPermission(payMonth, dataPermission, classLectureDetailQueryVo, status);

        return exportWageTeacherDollars(teacherDollarsDetailList,sysUserRoleService.showIdNoByCheckRoleNames(Principals.get().id));
    }

    public static SXSSFWorkbook exportWageTeacherDollars(List<TeacherDollarsDetailVo> teacherDollarsDetailList,Boolean showIdNo) {

        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("兼职信息");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"上课日期","期数","班级编号","班级","业务组","段次","科目","年级","产品线","教师","电话号码","身份证","工资账号","班级总讲次","任教讲次","第几讲","每讲基本课酬","绩效系数","其他或特殊课酬","备注","发薪月份","是否已确认","确认人","确认时间"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        for (TeacherDollarsDetailVo teacherDollarsDetailVo:teacherDollarsDetailList){
            int cellNum = 0;
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(teacherDollarsDetailVo.getClassDate()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(teacherDollarsDetailVo.getPeriodName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(teacherDollarsDetailVo.getClassNo()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(teacherDollarsDetailVo.getClassName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(teacherDollarsDetailVo.getBusTeamName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(teacherDollarsDetailVo.getSegmentNo()==null?"":teacherDollarsDetailVo.getSegmentNo().toString());

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(teacherDollarsDetailVo.getSubjectName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(teacherDollarsDetailVo.getGradeName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(teacherDollarsDetailVo.getProductName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(teacherDollarsDetailVo.getTeacherName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(teacherDollarsDetailVo.getPhoneNo()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(showIdNo?teacherDollarsDetailVo.getIdNo():""));

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(teacherDollarsDetailVo.getSalaryAccount()));

     /*       cell = row.createCell(cellNum++);
            cell.setCellValue(EnumUtils.getName(JobNatureEnum.values() ,teacherDollarsDetailVo.getJobNature()));
*/
            cell = row.createCell(cellNum++);
            cell.setCellValue(teacherDollarsDetailVo.getLectureAmount());

            cell = row.createCell(cellNum++);
            cell.setCellValue(teacherDollarsDetailVo.getTotalLectureNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(teacherDollarsDetailVo.getLectureNums());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(teacherDollarsDetailVo.getBaseDollar().doubleValue());

            cell = row.createCell(cellNum++);
            cell.setCellValue(teacherDollarsDetailVo.getCoefficientPerformance());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(teacherDollarsDetailVo.getSpecialDollar().doubleValue());

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(teacherDollarsDetailVo.getRemark()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.formatDate(teacherDollarsDetailVo.getPayMonth(),"yyyy-MM-dd"));

            cell = row.createCell(cellNum++);
            cell.setCellValue(teacherDollarsDetailVo.getConfirmStatus()==1?"是":"否");

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(teacherDollarsDetailVo.getOperatorName()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.formatDate(teacherDollarsDetailVo.getConfirmTime(),"yyyy-MM-dd HH:mm:ss"));


        }
        return excel;
    }

}